package xperiment.metaphor.model.entity;

import xperiment.metaphor.model.*;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * A financial period
 * @author Mark Ashworth
 * @version 1.0.0
 */
public class FinancialPeriod extends DomainObject implements Persistent {
    public static final long serialVersionUID = 1L;
    
    /* The unique database id for the object */
    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name = "financial_period_id", unique = true, nullable = false)
    private Long id = null;
    
    /** The start of the financial period */
    private Date start;
    /** The end of the financial period */
    private Date end;
    /** Whether the financial period if closed */
    private boolean closed;
    
    private boolean enabled = true;
    /**
     * Default constructor
     */
    public FinancialPeriod() {
        super();
    }
    /**
     * Constructs the financial period with the start and end dates of 
     * the period.
     * 
     * @param start The start of the financial period
     * @param end The end of the financial period
     */
    public FinancialPeriod(Date start, Date end) {
        if (start == null) throw new IllegalArgumentException("The start date of the financial period may not be null");
        if (end == null) throw new IllegalArgumentException("The end date of the financial period may not be null");
        if (end.before(start)) throw new IllegalArgumentException("The end date of a financial period may not be before the start date");
        
        this.start = new Date(start.getTime());
        this.end = new Date(end.getTime());
    }

    @Override
	@Id @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name = "financial_period_id", unique = true, nullable = false)
    public Long getId() {
        return this.id;
    }
    
    public Date getEnd() {
        return end;
    }

    public void setEnd(Date end) {
        this.end = end;
    }

    public Date getStart() {
        return start;
    }

    public void setStart(Date start) {
        this.start = start;
    }

    public boolean isClosed() {
        return closed;
    }

    public void setClosed(boolean closed) {
        this.closed = closed;
    }
    
    /**
     * Whether the financial period is enabled
     * @return boolean
     */
    public boolean isEnabled() {
        return this.enabled;
    }

    /**
     * Whether the financial period is enabled
     * @param enabled The new value
     */
    public void setEnabled(boolean enabled) {
        boolean old = this.enabled;
		this.enabled = enabled;
		firePropertyChange("enabled", old, this.enabled);
    }
    
    /**
     * Determines if the financial period passed overlaps this financial period
     * @param period The financial period to check against
     * @return If the financial periods overlap
     */
    public boolean overlaps(FinancialPeriod period) {
        if (period == null) return false;
        if (this.start == null || this.end == null) return false;
        if (period.getStart() == null || period.getEnd() == null) return false;
        
        if (this.start.after(period.getStart()) && this.start.before(period.getEnd())) {
            return true;
        } else if (this.end.after(period.getStart()) && this.end.before(period.getEnd())) {
            return true;
        } else if (period.getStart().after(this.start) && period.getStart().before(this.end)) {
            return true;
        } else if (period.getEnd().after(this.start) && period.getEnd().before(this.end)) {
            return true;
        } else {
            return false;
        }
    }
}
